import { data, DataCode, DataItem, DataTable, DataText, DataType } from "@/data"
import { generatorArr, useAnimationFrame } from "@/utils"
import hljs from "highlight.js"

const oApp = document.getElementById('scroll-content') as HTMLDivElement

const init = async () => {
  const data = await getInitData()
  setPrint(data)
}

const getInitData = async (): Promise<typeof data> => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(data)
    }, 1500)
  })
}

// 执行数据打印操作
const setPrint = (requestData: Array<DataItem>) => {
  const interator = generatorArr(data)

  requestData.forEach(() => interator.use((dataItem, next) => {
    switch (dataItem['dataType']) {
      case DataType['Text']:
        handleText(dataItem, next)
        break;
      case DataType['Table']:
        handleTable(dataItem, next)
        break;
      case DataType['Code']:
        handleCode(dataItem, next)
        break;
    }
  }))

  // 执行
  interator.next()
}

// 处理 text 文本
const handleText = (dataText: DataText, next: () => void) => {
  const { data, dataType } = dataText
  let strIndex = 0,
    len = data.length

  const startFn = useAnimationFrame((clear) => {
    if (strIndex >= len) {
      // 完成
      console.log('文本打印完成....')
      next()
      return clear()
    }

    oApp.innerHTML += data[strIndex]
    strIndex++
  }, 20)

  startFn()
}

// 处理 表格数据
const handleTable = (dataTable: DataTable, arrNext: () => void) => {
  const { data, dataType } = dataTable,
    tableID = `${Date.now()}_table`,
    keys = Object.keys(data[0]) // 表头 key 顺序

  // 初始化表格 + 标题
  const initTableHead = () => {
    const oTable = document.createElement('table'),
      tHead = document.createElement('thead'),
      oTr = document.createElement('tr')

    Object.keys(data[0]).forEach(key => {
      const oTh = document.createElement('th')

      oTh.innerHTML = key
      oTr.appendChild(oTh)
    })

    tHead.appendChild(oTr)
    oTable.id = tableID
    oTable.appendChild(tHead)

    oApp.appendChild(oTable)
  }

  // 打印内容
  const initTableBody = () => {
    const iterator = generatorArr(data),
      tBody = document.createElement('tbody'),
      oTable = document.getElementById(tableID)

    if (!oTable) return
    oTable.appendChild(tBody)

    data.forEach(() => iterator.use((dataItem, next) => {
      const oTr = document.createElement('tr')

      // 处理<td></td>内容
      const keyIterator = generatorArr(keys)

      keys.forEach(() => keyIterator.use((key, keyNext) => {
        const oTd = document.createElement('td')
        let strIndex = 0
        
        const start = useAnimationFrame((clear) => {
          if (strIndex >= dataItem[key]['length']) {
            // 完成
            if (key === keys.at(-1)) {
              // 最后一个 key 完成
              next()
            }

            // 最后一个
            if (key === keys.at(-1) && Object.is(dataItem, data.at(-1))) {
              arrNext()
            }

            keyNext()
            return clear()
          }

          oTd.innerHTML += dataItem[key][strIndex]
          strIndex++
        }, 30)

        oTr.appendChild(oTd)
        start()
      }))

      tBody.appendChild(oTr)
      keyIterator.next()
    }))

    iterator.next()
  }

  const init = () => {
    initTableHead()
    initTableBody()
  }

  init()
}

// 处理 高亮代码块
const handleCode = (dataCode: DataCode, next: () => void) => {
  const { data, language } = dataCode

  const oPre = document.createElement('pre'),
    oCode = document.createElement('code')

  let strIndex = 0, strLen = data.length
  const start = useAnimationFrame((clear) => {
    if (strIndex >= strLen) {
      // 完成
      return clear()
    }

    const highlightObj = hljs.highlight(data.slice(0, strIndex), {
      language
    })

    oCode.innerHTML = highlightObj.value
    strIndex++
  }, 20)

  oCode.classList.add(language)
  oPre.appendChild(oCode)
  oApp.appendChild(oPre)
  hljs.highlightElement(oCode)
  start()
}

export default {
  init
}